#pragma once

//WGLENGINE_DLL
#ifdef WGLENGINE_DLL
#define WGLENGINE_EXPORT __declspec(dllexport)
#else
#define WGLENGINE_EXPORT __declspec(dllimport)
#endif

#include "Transform.h"
#include "glm\glm.hpp"

#include <algorithm>
#include <memory>
#include <vector>

class WRenderer;
class WGLENGINE_EXPORT WObject
{
protected:
	std::unique_ptr<Transform> transform;
	bool enabled;

public:
	WObject()
	{
		enabled = true;
		renderOrder = 100;
		transform = std::unique_ptr<Transform>(new Transform());
	}

	~WObject(){}

	void SetRenderOrder(unsigned int renderOrder) 
	{
		this->renderOrder = renderOrder;
	}

	void Translate(glm::vec3 vec)
	{
		transform->Translate(vec);
	}

	glm::mat4 GetTransformMatrix()
	{
		return transform->GetModelMatrix();
	}
	
	bool IsEnabled()
	{
		return enabled;	
	}

	void SetEnable(bool val)
	{
		enabled = val;
	}
	
	
	virtual void PreUpdate()
	{

	}

	virtual void Update(std::shared_ptr<WRenderer> renderer)
	{

	}

	virtual void PreRender()
	{

	}
	
	virtual void Render()
	{

	}
	
	static void RegisterPreUpdater(std::shared_ptr<WObject> updater);
	static void UnregisterPreUpdater(std::shared_ptr<WObject> updater);
	static void PreUpdateObjects();
	
	static void RegisterUpdater(std::shared_ptr<WObject> updater);
	static void UnregisterUpdater(std::shared_ptr<WObject> updater);
	static void UpdateObjects(std::shared_ptr<WRenderer> renderer);

	static void RegisterPreRenderObj(std::shared_ptr<WObject> obj);
	static void UnregisterPreRenderObj(std::shared_ptr<WObject> obj);
	static void PreRenderObjects();
	

private:
	unsigned int renderOrder;
	
	static std::vector<std::shared_ptr<WObject>> PreUpdateList;
	static std::vector<std::shared_ptr<WObject>> UpdateList;
	
	static std::vector<std::shared_ptr<WObject>> PreRenderList;
};
